using System.Collections.Generic;
using System;
using SharpArch.Core;
using GoldenBicycleCompany.Core;
using GoldenBicycleCompany.ApplicationServices.ViewModels;
using GoldenBicycleCompany.Core.QueryDtos;
using GoldenBicycleCompany.Core.RepositoryInterfaces;
 

namespace GoldenBicycleCompany.ApplicationServices
{
    public class LocationManagementService : ILocationManagementService
    {
        public LocationManagementService(ILocationRepository locationRepository) {
            Check.Require(locationRepository != null, "locationRepository may not be null");

            this.locationRepository = locationRepository;
        }

        public Location Get(int id) {
            return locationRepository.Get(id);
        }

        public IList<Location> GetAll() {
            return locationRepository.GetAll();
        }

        public IList<LocationDto> GetLocationSummaries() {
            return locationRepository.GetLocationSummaries();
        }

        public LocationFormViewModel CreateFormViewModel() {
            LocationFormViewModel viewModel = new LocationFormViewModel();
            return viewModel;
        }

        public LocationFormViewModel CreateFormViewModelFor(int locationId) {
            Location location = locationRepository.Get(locationId);
            return CreateFormViewModelFor(location);
        }

        public LocationFormViewModel CreateFormViewModelFor(Location location) {
            LocationFormViewModel viewModel = CreateFormViewModel();
            viewModel.Location = location;
            return viewModel;
        }

        public ActionConfirmation SaveOrUpdate(Location location) {
            if (location.IsValid()) {
                locationRepository.SaveOrUpdate(location);

                ActionConfirmation saveOrUpdateConfirmation = ActionConfirmation.CreateSuccessConfirmation(
                    "The location was successfully saved.");
                saveOrUpdateConfirmation.Value = location;

                return saveOrUpdateConfirmation;
            }
            else {
                locationRepository.DbContext.RollbackTransaction();

                return ActionConfirmation.CreateFailureConfirmation(
                    "The location could not be saved due to missing or invalid information.");
            }
        }

        public ActionConfirmation UpdateWith(Location locationFromForm, int idOfLocationToUpdate) {
            Location locationToUpdate = 
                locationRepository.Get(idOfLocationToUpdate);
            TransferFormValuesTo(locationToUpdate, locationFromForm);

            if (locationToUpdate.IsValid()) {
                ActionConfirmation updateConfirmation = ActionConfirmation.CreateSuccessConfirmation(
                    "The location was successfully updated.");
                updateConfirmation.Value = locationToUpdate;

                return updateConfirmation;
            }
            else {
                locationRepository.DbContext.RollbackTransaction();

                return ActionConfirmation.CreateFailureConfirmation(
                    "The location could not be saved due to missing or invalid information.");
            }
        }

        public ActionConfirmation Delete(int id) {
            Location locationToDelete = locationRepository.Get(id);

            if (locationToDelete != null) {
                locationRepository.Delete(locationToDelete);

                try {
                    locationRepository.DbContext.CommitChanges();
                    
                    return ActionConfirmation.CreateSuccessConfirmation(
                        "The location was successfully deleted.");
                }
                catch {
                    locationRepository.DbContext.RollbackTransaction();

                    return ActionConfirmation.CreateFailureConfirmation(
                        "A problem was encountered preventing the location from being deleted. " +
                        "Another item likely depends on this location.");
                }
            }
            else {
                return ActionConfirmation.CreateFailureConfirmation(
                    "The location could not be found for deletion. It may already have been deleted.");
            }
        }

        private void TransferFormValuesTo(Location locationToUpdate, Location locationFromForm) {
		    locationToUpdate.Name = locationFromForm.Name;
			locationToUpdate.StreetAddress = locationFromForm.StreetAddress;
			locationToUpdate.Inventory = locationFromForm.Inventory;
        }

        ILocationRepository locationRepository;
    }
}
